/*
 * @Author: moeWang
 * @Date: 2021-09-08 13:53:59
 * @LastEditTime: 2021-09-08 14:27:55
 * @LastEditors: moeWang
 * @Description: 模板方法模式
 * @FilePath: \front-end-design-mode\code\TemplateMethod.js
 */

/* 
    基于继承的设计模式-模板方法
    两部分组成  一部分抽象父类，二部分实现子类
*/
// 抽象类饮料 四个步骤 煮水、冲泡、倒进杯子、加调料
// var Beverage = function () { }

// Beverage.prototype.boilWater = function () {
//     console.log('boil water');
// }

// Beverage.prototype.brew = function () {
//     throw new Error('子类必须重写brew方法')
// } // 空方法，子类重写
// Beverage.prototype.pourInCup = function () {
//     throw new Error('子类必须重写pourInCup方法')
// }
// Beverage.prototype.addCondiments = function () {
//     throw new Error('子类必须重写addCondiments方法')
// }
// /*
//     Beverage.prototype.init是模板方法，其中封装了子类的算法框架，指导子类以何种顺序执行哪些方法。
// */
// Beverage.prototype.init = function () {
//     this.boilWater()
//     this.brew()
//     this.pourInCup()
//     this.addCondiments()
// }

// var Coffee = function () { }
// Coffee.prototype = new Beverage()

// Coffee.prototype.brew = function () {
//     console.log('沸水冲☕');
// }
// Coffee.prototype.pourInCup = function () {
//     console.log('☕倒进杯子');
// }
// Coffee.prototype.addCondiments = function () {
//     console.log('加糖和牛奶');
// }
// var coffee = new Coffee()
// coffee.init()

// var Tea = function () { }
// Tea.prototype = new Beverage()
// Tea.prototype.brew = function () {
//     console.log('沸水冲茶叶');
// }
// Tea.prototype.pourInCup = function () {
//     console.log('茶倒进杯子');
// }
// Tea.prototype.addCondiments = function () {
//     console.log('加🍋');
// }
// var tea = new Tea()
// tea.init()

// 钩子方法hook
var Beverage = function () { }

Beverage.prototype.boilWater = function () {
    console.log('boil water');
}

Beverage.prototype.brew = function () {
    throw new Error('子类必须重写brew方法')
} // 空方法，子类重写
Beverage.prototype.pourInCup = function () {
    throw new Error('子类必须重写pourInCup方法')
}
Beverage.prototype.addCondiments = function () {
    throw new Error('子类必须重写addCondiments方法')
}
Beverage.prototype.customerWantsCondiments = function () {
    return true
}
/*
    Beverage.prototype.init是模板方法，其中封装了子类的算法框架，指导子类以何种顺序执行哪些方法。
*/
Beverage.prototype.init = function () {
    this.boilWater()
    this.brew()
    this.pourInCup()
    if (this.customerWantsCondiments()) {
        this.addCondiments()
    }
}

var CoffeeWithHook = function () { }
CoffeeWithHook.prototype = new Beverage()

CoffeeWithHook.prototype.brew = function () {
    console.log('沸水冲☕');
}
CoffeeWithHook.prototype.pourInCup = function () {
    console.log('☕倒进杯子');
}
CoffeeWithHook.prototype.addCondiments = function () {
    console.log('加糖和牛奶');
}
CoffeeWithHook.prototype.customerWantsCondiments = function () {
    // 交互操作是否需要调料
    return false
}
var coffee = new CoffeeWithHook()
coffee.init()

var Tea = function () { }
Tea.prototype = new Beverage()
Tea.prototype.brew = function () {
    console.log('沸水冲茶叶');
}
Tea.prototype.pourInCup = function () {
    console.log('茶倒进杯子');
}
Tea.prototype.addCondiments = function () {
    console.log('加🍋');
}
var tea = new Tea()
tea.init()
